package com.swak.paxos;

import java.io.Serializable;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;

import com.swak.paxos.protocol.PaxosForward;
import com.swak.paxos.protocol.PaxosMessage;
import com.swak.reactivex.cluster.Member;
import com.swak.reactivex.transport.Message;
import com.swak.utils.StringUtils;

/**
 * 代表一个节点.
 * 
 * @author 618lf
 */
public interface Node {

	/**
	 * nodeId
	 * 
	 * @return
	 */
	String id();

	/**
	 * 网络节点
	 * 
	 * @return
	 */
	Member member();

	/**
	 * 提交一个提案.
	 * 
	 * @param groupIdx 业务分组
	 * @param sValue 提交的数据
	 * @param smID 状态机
	 * @param useMaster 使用 Master 提交数据
	 */
	CompletableFuture<Void> propose(int groupIdx, Serializable value, int smID, boolean useMaster);

	/**
	 * 提交一个提案.
	 * 
	 * @param groupIdx 业务分组
	 * @param sValue 提交的数据
	 * @param smID 状态机
	 */
	CompletableFuture<Void> propose(int groupIdx, Serializable value, int smID);

	/**
	 * 节点变化
	 * 
	 * @param member
	 * @param members
	 * @param add
	 */
	void onMemberShipChanaged(Member member, List<Member> members, boolean add);

	/**
	 * 收到消息
	 * 
	 * @param message
	 */
	void onReceiveMessage(Message message);

	/**
	 * 广播消息
	 * 
	 * @param message 消息
	 */
	void broadcastMessage(PaxosMessage message);
	
	/**
	 * 单播消息
	 * 
	 * @param message 消息
	 */
	void broadcastMessage(String nodeID, PaxosMessage message);

	/**
	 * 单播消息
	 * 
	 * @param message 消息
	 */
	void broadcastMessageToFollower(PaxosMessage message);

	/**
	 * 发送消息.
	 * 
	 * @param nodeID  节点
	 * @param message 消息
	 */
	void sendMessage(String nodeID, PaxosMessage message);
	
	/**
	 * 发送消息.
	 * 
	 * @param nodeID  节点
	 * @param message 消息
	 */
	void sendMessage(String nodeID, PaxosForward message);

	/**
	 * 关闭
	 */
	void close();

	/**
	 * 初始化一个 NodeID.
	 * 
	 * @param nodeID
	 * @return
	 */
	static String newNodeID(String nodeID) {
		if (StringUtils.isBlank(nodeID)) {
			return UUID.randomUUID().toString();
		}
		return nodeID;
	}
}